



#ifndef _PDF_LAYER_H_
#define _PDF_LAYER_H_

#include <wx/dynarray.h>
#include <wx/string.h>

#include "wx/pdfdocdef.h"

class WXDLLIMPEXP_FWD_PDFDOC wxPdfDictionary;

class WXDLLIMPEXP_FWD_PDFDOC wxPdfLayer;
WX_DEFINE_USER_EXPORTED_ARRAY_PTR(wxPdfLayer*, wxPdfArrayLayer, class WXDLLIMPEXP_PDFDOC);

/// Optional content group types
enum wxPdfOcgType
{
  wxPDF_OCG_TYPE_UNKNOWN,
  wxPDF_OCG_TYPE_LAYER,
  wxPDF_OCG_TYPE_TITLE,
  wxPDF_OCG_TYPE_MEMBERSHIP
};

const int wxPDF_OCG_INTENT_DEFAULT = 0;
const int wxPDF_OCG_INTENT_VIEW    = 1;
const int wxPDF_OCG_INTENT_DESIGN  = 2;

/// OCG visibility policy
enum wxPdfOcgPolicy
{
  wxPDF_OCG_POLICY_ALLON,
  wxPDF_OCG_POLICY_ANYON,
  wxPDF_OCG_POLICY_ANYOFF,
  wxPDF_OCG_POLICY_ALLOFF
};

/// Base class for optional content. (For internal use only)
class WXDLLIMPEXP_PDFDOC wxPdfOcg
{
public:
  /// Constructor
  wxPdfOcg();

  /// Destructor
  virtual ~wxPdfOcg();

    void SetIndex(int index) { m_index = index; }

  /// Get OCG index
  int  GetIndex() const { return m_index; }

    void SetObjIndex(int n) { m_n = n; }

  /// Get object index
  int  GetObjIndex() const { return m_n; }

  /// Check whether OCG is initialized
  bool IsOk() const;

  /// Get 
  wxPdfOcgType GetType() const { return m_type; }

protected:
  wxPdfOcgType   m_type;      
private:
  int            m_index;     ///< Index number of this OCG
  int            m_n;         ///< OCG object index
};

/// Class for a layer with optional content.
class WXDLLIMPEXP_PDFDOC wxPdfLayer : public wxPdfOcg
{
public:
  /// Constructor
      
  wxPdfLayer(const wxString& name);

  /// Destructor
  virtual ~wxPdfLayer();

  /// Get the name of the layer
  
  wxString GetName() const { return m_name; }

  /// Get the layer title
  
  wxString GetTitle() const { return m_title; }

  /// Set Optional Content Group (OCG) Intent
  
  void SetIntent(const unsigned int intent) { m_intent |= intent; };

  /// Get Optional Content Group (OCG) Intent
  
  int GetIntent() const { return m_intent; };

  /// Clear Optional Content Group (OCG) Intent
  
  void ClearIntent(const unsigned int intent) { m_intent &= ~intent; };

  /// Set the initial visibility of the layer
  
  void SetOn(bool on) { m_on = on; }

  /// Get the initial visibility of the layer
  
  bool IsOn() const  { return m_on; }

  /// Set the visibility of the layer on the layer panel
  
  void SetOnPanel(bool onPanel) { m_onPanel = onPanel; }

  /// Get the layer visibility on the layer panel
  
  bool IsOnPanel() const { return m_onPanel; }

  /// Add child layer
      
  bool AddChild(wxPdfLayer* child);

  /// Get parent layer
      
  wxPdfLayer* GetParent() const { return m_parent; }

  bool HasChildren() const { return !m_children.IsEmpty(); }
  
  /// Get the list of child layers
      
  wxPdfArrayLayer GetChildren() const { return m_children; }

  /// Set the creator's info
      
  void SetCreatorInfo(const wxString& creator, const wxString& subtype);

  /// Set the language
      
  void SetLanguage(const wxString& lang, bool preferred);

  /// Set the export state
      
  void SetExport(bool exportState);

  /// Set the range of zoom magnification
      
  void SetZoom(double min, double max);

  /// Set the print state
      
  void SetPrint(const wxString& subtype, bool printState);

  /// Set the view state
      
  void SetView(bool viewState);

  /// Get the usage dictionary
  
  wxPdfDictionary* GetUsage() const { return m_usage; }

  /// Create a title layer
      
  static wxPdfLayer* CreateTitle(const wxString& title);

protected:
  /// Copy constructor
  wxPdfLayer(const wxPdfLayer& encoding);

  /// Assignment operator
  wxPdfLayer& operator=(const wxPdfLayer& encoding);

  /// Set the parent of the layer
  bool SetParent(wxPdfLayer* parent);

  /// Allocate the usage dictonary
  wxPdfDictionary* AllocateUsage();

private:
  wxString         m_name;     ///< Name of the layer
  wxString         m_title;    ///< Title of a layer group
  int              m_intent;   ///< Intended use
  bool             m_on;       ///< Flag for ON/OFF state
  bool             m_onPanel;  ///< Flag for ON/OFF state on layer panel
  wxPdfLayer*      m_parent;   ///< parent layer
  wxPdfArrayLayer  m_children; ///< list of child layers
  wxPdfDictionary* m_usage;    ///< usage dictionary
};

/// Class for a layer with optional content.
class WXDLLIMPEXP_PDFDOC wxPdfLayerMembership : public wxPdfOcg
{
public:
  /// Constructor
  wxPdfLayerMembership();

  /// Destructor
  virtual ~wxPdfLayerMembership();

  /// Add layer
      
  bool AddMember(wxPdfLayer* layer);

  /// Get a list of the layers
  wxPdfArrayLayer GetMembers() const;

  /// Set visibility policy
      
  void SetVisibilityPolicy(wxPdfOcgPolicy policy);

  /// Get the visibility policy
  wxPdfOcgPolicy GetVisibilityPolicy() const;

protected:
  /// Copy constructor
  wxPdfLayerMembership(const wxPdfLayerMembership& layer);

  /// Assignment operator
  wxPdfLayerMembership& operator=(const wxPdfLayerMembership& layer);

private:
  wxPdfArrayLayer m_layers; ///< Array of layers which are members
  wxPdfOcgPolicy  m_policy; ///< Visibility policy
};

/// Class for a group of layers with optional content.
class WXDLLIMPEXP_PDFDOC wxPdfLayerGroup
{
public:
  /// Constructor
  wxPdfLayerGroup();

  /// Destructor
  virtual ~wxPdfLayerGroup();

  /// Copy constructor
  wxPdfLayerGroup(const wxPdfLayerGroup& layer);

  /// Assignment operator
  wxPdfLayerGroup& operator=(const wxPdfLayerGroup& layer);

  /// Add layer
      
  bool Add(wxPdfLayer* layer);

  /// Get list of group members
  wxPdfArrayLayer GetGroup() const;

private:
  wxPdfArrayLayer m_layers; ///< Array of layers which are members of the radio group
};

#endif
